package com.compomics.prioritizer.general.gui;

import com.compomics.prioritizer.db.accessors.*;
import com.compomics.prioritizer.general.PrioritizerSingelton;

import javax.swing.*;
import javax.mail.*;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.AddressException;
import java.awt.*;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import java.util.Collection;

import org.masukomi.aspirin.core.MailQue;
import org.masukomi.aspirin.core.MailWatcher;
import org.apache.mailet.MailAddress;

/**
 * Created by IntelliJ IDEA.
 * User: niklaas
 * Date: 5-mrt-2009
 * Time: 13:41:07
 * To change this template use File | Settings | File Templates.
 */
public class MailSendingPanel extends JFrame {
    private JProgressBar progressBar1;
    private JTextArea txtMessage;
    private JLabel sendingMailLabel;
    private JPanel jpanContent;


    /**
     * The PrioritizerSingelton
     */
    private PrioritizerSingelton iPrioritizerSingelton;


    public MailSendingPanel() {
        $$$setupUI$$$();
        iPrioritizerSingelton = PrioritizerSingelton.getInstance();

        Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
        this.setContentPane(jpanContent);
        this.setLocation((screen.width / 3), (screen.height / 4));
        this.setSize(300, 300);
        this.setVisible(true);
    }


    public void projectDone(Connection aConn, Project aProject) {

        try {
            aProject = Project.getProjectById(aConn, aProject.getProjectid());
            User lProjectOwner = User.getUserById(aConn, aProject.getL_userid());
            User[] lAdmins = User.getAdmins(aConn);
            User[] lOperators = Instrument_to_user.getOperatorsByInstrumentId(aConn, aProject.getL_instrumentid_accepted());
            Instrument lInstrument = Instrument.getInstrumentById(aConn, aProject.getL_instrumentid_accepted());
            String title = "The project " + aProject.getName() + " is done";
            String message = "Hello," +
                    "\nThe project \"" + aProject.getName() + "\" is done!" +
                    "\nThe project was created on : " + aProject.getCreationdate() +
                    "\nThe project was accepted on : " + aProject.getAccepteddate() +
                    "\nThe project had a top priority on : " + aProject.getTopprioritydate() +
                    "\nThe project was done on : " + aProject.getEndanalysisdate() +
                    "\n\nThis project was analysed with the " + lInstrument.getName() + " by " + getOperatorsString(lOperators) + ".";
            String[] to = new String[lAdmins.length + 1];
            for (int t = 0; t < to.length - 1; t++) {
                to[t] = lAdmins[t].getE_mail();
            }
            to[lAdmins.length] = lProjectOwner.getE_mail();
            boolean sendOk = this.postMail(to, title, message);
            if (!sendOk) {
                JOptionPane.showMessageDialog(new JFrame(), "An e-mail could not be send!", "ERROR", JOptionPane.ERROR_MESSAGE);
            }
        } catch (SQLException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }


    public void projectTopPriority(Connection aConn, Project aProject) {

        try {
            aProject = Project.getProjectById(aConn, aProject.getProjectid());
            User lProjectOwner = User.getUserById(aConn, aProject.getL_userid());
            Instrument lInstrument = Instrument.getInstrumentById(aConn, aProject.getL_instrumentid_accepted());
            User[] lOperators = Instrument_to_user.getOperatorsByInstrumentId(aConn, aProject.getL_instrumentid_accepted());
            String title = "Your project " + aProject.getName() + " is first in the priority ranking";
            String message = "Hello," +
                    "\nYour project \"" + aProject.getName() + "\" is first in the priority ranking!" +
                    "\nThe project was created on : " + aProject.getCreationdate() +
                    "\nThe project was accepted on : " + aProject.getAccepteddate() +
                    "\n\nThis project will be analysed with the " + lInstrument.getName() + " by " + getOperatorsString(lOperators) + ".";

            String[] to = {lProjectOwner.getE_mail()};
            boolean sendOk = this.postMail(to, title, message);
            if (!sendOk) {
                JOptionPane.showMessageDialog(new JFrame(), "An e-mail could not be send!", "ERROR", JOptionPane.ERROR_MESSAGE);
            }
        } catch (SQLException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

    }

    public void newProject(Connection aConn, Project aProject) {

        try {
            User lProjectOwner = User.getUserById(aConn, aProject.getL_userid());
            User[] lAdmins = User.getAdmins(aConn);
            String title = "New project that needs to be accepted";
            String message = "Hello," +
                    "\nA new project (" + aProject.getName() + ") was created by " + lProjectOwner.getName() + "." +
                    "\nThis project must be accepted." +
                    "\nThanks";
            String[] to = new String[lAdmins.length];
            for (int t = 0; t < lAdmins.length; t++) {
                to[t] = lAdmins[t].getE_mail();
            }
            boolean sendOk = this.postMail(to, title, message);
            if (!sendOk) {
                JOptionPane.showMessageDialog(new JFrame(), "An e-mail could not be send!", "ERROR", JOptionPane.ERROR_MESSAGE);
            }
        } catch (SQLException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

    }

    public void projectAccepted(Connection aConn, Project aProject) {

        try {
            Instrument lInstProposed = Instrument.getInstrumentById(aConn, aProject.getL_instrumentid_proposed());
            Instrument lInstAccepted = Instrument.getInstrumentById(aConn, aProject.getL_instrumentid_accepted());
            User lProjectOwner = User.getUserById(aConn, aProject.getL_userid());
            User[] lOperators = Instrument_to_user.getOperatorsByInstrumentId(aConn, aProject.getL_instrumentid_accepted());
            String title = "The new project '" + aProject.getName() + "' was accepted";
            String message = "Hello," +
                    "\nThe new project (" + aProject.getName() + ") was accepted ." +
                    "\nThe proposed instrument was: " + lInstProposed +
                    "\nThe accepted instrument was: " + lInstAccepted +
                    "\nThanks";
            String[] to = new String[]{lProjectOwner.getE_mail(), lOperators[0].getE_mail()};
            boolean sendOk = this.postMail(to, title, message);
            if (!sendOk) {
                JOptionPane.showMessageDialog(new JFrame(), "An e-mail could not be send!", "ERROR", JOptionPane.ERROR_MESSAGE);
            }
        } catch (SQLException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

    }

    public void projectStatusChanged(Connection aConn, Project aProject) {

        try {
            Instrument lInstAccepted = Instrument.getInstrumentById(aConn, aProject.getL_instrumentid_accepted());
            User lProjectOwner = User.getUserById(aConn, aProject.getL_userid());
            User[] lOperators = Instrument_to_user.getOperatorsByInstrumentId(aConn, aProject.getL_instrumentid_accepted());
            User[] lAdmin = User.getAdmins(aConn);
            Log lLog = Log.getNewestLogForProject(aConn, aProject.getProjectid());
            String title = "The status of the project '" + aProject.getName() + "' was changed";
            String message = "Hello," +
                    "\nThe status of the project '" + aProject.getName() + "' was changed" +
                    "\nThe new status is: \"" + lLog.getStatus() + "\"" +
                    "\nThanks";
            String[] to = new String[2 + lAdmin.length];
            to[0] = lProjectOwner.getE_mail();
            to[1] = lOperators[0].getE_mail();
            for (int i = 2; i < to.length; i++) {
                to[i] = lAdmin[i - 2].getE_mail();
            }
            boolean sendOk = this.postMail(to, title, message);
            if (!sendOk) {
                JOptionPane.showMessageDialog(new JFrame(), "An e-mail could not be send!", "ERROR", JOptionPane.ERROR_MESSAGE);
            }
        } catch (SQLException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

    }

    public void instrumentChanged(Connection aConn, Project aProject) {

        try {
            Instrument lInstAccepted = Instrument.getInstrumentById(aConn, aProject.getL_instrumentid_accepted());
            User lProjectOwner = User.getUserById(aConn, aProject.getL_userid());
            User[] lOperators = Instrument_to_user.getOperatorsByInstrumentId(aConn, aProject.getL_instrumentid_accepted());
            String title = "The project '" + aProject.getName() + "' instrument was changed";
            String message = "Hello," +
                    "\nThe instrument for project (" + aProject.getName() + ") was changed." +
                    "\nThe changed instrument is: " + lInstAccepted +
                    "\nThanks";
            String[] to = new String[]{lProjectOwner.getE_mail(), lOperators[0].getE_mail()};
            boolean sendOk = this.postMail(to, title, message);
            if (!sendOk) {
                JOptionPane.showMessageDialog(new JFrame(), "An e-mail could not be send!", "ERROR", JOptionPane.ERROR_MESSAGE);
            }
        } catch (SQLException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

    }

    public void projectModified(Connection aConn, Project aProject) {
        try {
            aProject = Project.getProjectById(aConn, aProject.getProjectid());
            User lProjectOwner = User.getUserById(aConn, aProject.getL_userid());
            Instrument lInstrument = Instrument.getInstrumentById(aConn, aProject.getL_instrumentid_accepted());
            User[] lOperators = Instrument_to_user.getOperatorsByInstrumentId(aConn, aProject.getL_instrumentid_accepted());
            String title = "The project " + aProject.getName() + " is modified";
            String message = "Hello," +
                    "\nThe project \"" + aProject.getName() + "\" was modified by " + lProjectOwner.getName() + ".";
            String[] to = {lOperators[0].getE_mail()};
            boolean sendOk = this.postMail(to, title, message);
            if (!sendOk) {
                JOptionPane.showMessageDialog(new JFrame(), "An e-mail could not be send!", "ERROR", JOptionPane.ERROR_MESSAGE);
            }
        } catch (SQLException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }

    public void prioritiesChanged(Connection aConn, long aInstrumentId) {
        try {
            Instrument lInstrument = Instrument.getInstrumentById(aConn, aInstrumentId);
            User[] lOperators = Instrument_to_user.getOperatorsByInstrumentId(aConn, aInstrumentId);
            String title = "The priorities for the " + lInstrument.getName() + " were changed";
            Project[] projects = Project.getAllUnfinishedProjectsForInstrument(aConn, lInstrument.getInstrumentid());
            String message = "Hello," +
                    "\nThe priorities for the " + lInstrument.getName() + " were changed. This is the new priority list.";
            for (int p = 0; p < projects.length; p++) {
                message = message + "\n" + (p + 1) + ". " + projects[p].getName();
            }
            String[] to = {lOperators[0].getE_mail()};
            boolean sendOk = this.postMail(to, title, message);
            if (!sendOk) {
                JOptionPane.showMessageDialog(new JFrame(), "An e-mail could not be send!", "ERROR", JOptionPane.ERROR_MESSAGE);
            }
        } catch (SQLException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }

    public boolean postMail(String recipients[], String subject, String message) {

        this.setVisible(true);
        txtMessage.setText(message);
        progressBar1.setIndeterminate(true);

        //ToDo delete me

        System.out.println(subject);
        for (int i = 0; i < recipients.length; i++) {
            System.out.println(recipients[i]);
        }
        System.out.println(message);

        //ToDo delete me


        boolean debug = false;
        //properties for the connection with the server
        Properties props = new Properties();
        props.put("mail.smtp.host", iPrioritizerSingelton.getSMTP_HOST_NAME());
        props.put("mail.smtp.auth", "true");
        props.put("mail.debug", "true");
        props.put("mail.smtp.port", iPrioritizerSingelton.getSMTP_PORT());

        //create session with the server
        Session session = Session.getDefaultInstance(props, new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(iPrioritizerSingelton.getADDRESS(), iPrioritizerSingelton.getPass());
            }
        });

        session.setDebug(debug);
        // make the message
        Message msg = new MimeMessage(session);
        InternetAddress addressFrom = null;
        try {
            addressFrom = new InternetAddress(iPrioritizerSingelton.getADDRESS());
            msg.setFrom(addressFrom);
            InternetAddress[] addressTo = new InternetAddress[recipients.length + 1];
            for (int i = 0; i < recipients.length; i++) {
                addressTo[i] = new InternetAddress(recipients[i]);
            }
            addressTo[addressTo.length - 1] = new InternetAddress(iPrioritizerSingelton.getADDRESS());

            msg.setRecipients(Message.RecipientType.TO, addressTo);
            msg.setSubject(subject);
            msg.setContent(message, "text/plain");
            Transport.send(msg);

            this.dispose();

        } catch (AddressException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            return false;
        } catch (MessagingException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            return false;
        }
        //this.dispose();
        return true;
    }


    public void setEmailAdress(String aFrom) {
        iPrioritizerSingelton.setUserEmailAdress(aFrom);
    }

    private void createUIComponents() {
        sendingMailLabel = new JLabel("Sending mail ...");
    }

    private String getOperatorsString(User[] operatorsArray) {
        String concat = "";
        for (User lUser : operatorsArray) {
            concat += lUser.toString() + ", ";
        }
        concat = concat.substring(0, concat.lastIndexOf(", "));
        return concat;
    }

    /**
     * Method generated by IntelliJ IDEA GUI Designer
     * >>> IMPORTANT!! <<<
     * DO NOT edit this method OR call it in your code!
     *
     * @noinspection ALL
     */
    private void $$$setupUI$$$() {
        createUIComponents();
        jpanContent = new JPanel();
        jpanContent.setLayout(new GridBagLayout());
        sendingMailLabel.setText("Sending mail ...");
        GridBagConstraints gbc;
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.insets = new Insets(5, 5, 5, 5);
        jpanContent.add(sendingMailLabel, gbc);
        progressBar1 = new JProgressBar();
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 2;
        gbc.gridwidth = 2;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(5, 5, 5, 5);
        jpanContent.add(progressBar1, gbc);
        final JScrollPane scrollPane1 = new JScrollPane();
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.gridwidth = 2;
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.insets = new Insets(5, 5, 5, 5);
        jpanContent.add(scrollPane1, gbc);
        txtMessage = new JTextArea();
        scrollPane1.setViewportView(txtMessage);
    }

    /**
     * @noinspection ALL
     */
    public JComponent $$$getRootComponent$$$() {
        return jpanContent;
    }
}
